﻿package com.myp.flow
{
    import flash.events.*;
    import flash.utils.*;

    public class Flow extends EventDispatcher
    {
        private var _default:String;
        public var name:String;
        public var preventRequestSameSection:Boolean = true;
        private var _currentSection:String;
        public var alwaysForceRequest:Boolean = false;
        private var _history:Array;
        public var autoAccept:Boolean = false;
        public var ignoreUnexpectedAccepts:Boolean = true;
        private var _waitingAccept:Boolean = false;
        private var _nextSection:String;
        static var disp:EventDispatcher;
        public static var verbose:Boolean = true;
        private static var _levels:Dictionary;

        public function Flow(param1:IEventDispatcher = null)
        {
            super(param1);
            return;
        }// end function

        public function cancel() : void
        {
            this.say("se ha cancelado el ultimo request");
            this._waitingAccept = false;
            return;
        }// end function

        public function accept(param1:String = "Sin identificar") : void
        {
            if (!this._waitingAccept)
            {
                this.say("se ha llamado a accept() sin esperar un request desde: " + param1 + " > " + (this.ignoreUnexpectedAccepts ? ("[Rechazado autom?ticamente]") : ("[Procesado]")));
                if (this.ignoreUnexpectedAccepts)
                {
                    return;
                }// end if
            }// end if
            if (!this._history)
            {
                this._history = new Array();
            }// end if
            this._history.push(this._currentSection);
            this._currentSection = this._nextSection;
            this.say("accept " + this._currentSection + " (desde : " + param1 + ")");
            this._waitingAccept = false;
            var _loc_2:* = new FlowEvent(FlowEvent.CHANGE);
            _loc_2.currentSection = this._currentSection;
            this.dispatchEvent(_loc_2);
            Flow.dispatchEvent(new FlowEvent(FlowEvent.SOME_LEVEL_CHANGE));
            return;
        }// end function

        public function destroy() : void
        {
            delete _levels[this.name];
            return;
        }// end function

        public function overrideCurrentSection(param1:String) : void
        {
            this._currentSection = param1;
            this.say("se ha sobreescrito la secci?n actual " + param1);
            return;
        }// end function

        public function request(param1:String, param2:String, param3:Boolean = false) : void
        {
            var _loc_4:FlowEvent;
            if (this.preventRequestSameSection)
            {
                if (this._currentSection == param1)
                {
                    this.say("ya se esta en esta seccion");
                    return;
                }// end if
            }// end if
            this._nextSection = param1;
            this.say("request " + param1 + " desde " + param2);
            if (this.autoAccept)
            {
                this.say("    auto aceptando");
                this.accept();
            }// end if
            if (param3 || this.alwaysForceRequest)
            {
                this._waitingAccept = true;
                this.accept();
            }
            else
            {
                if (this._waitingAccept)
                {
                    this.say("se ha realizado un request a " + param1 + " sin haber aceptado un request anterior");
                }// end if
                this._waitingAccept = true;
                _loc_4 = new FlowEvent(FlowEvent.REQUEST);
                _loc_4.currentSection = this._currentSection;
                _loc_4.nextSection = this._nextSection;
                this.dispatchEvent(_loc_4);
                Flow.dispatchEvent(new FlowEvent(FlowEvent.SOME_LEVEL_REQUEST));
            }// end else if
            return;
        }// end function

        public function set defaultSection(param1:String) : void
        {
            this._default = param1;
            return;
        }// end function

        private function say(... args) : void
        {
            if (verbose)
            {
                trace("<<< FLOW " + this.name + " : " + args + " >>>");
            }// end if
            return;
        }// end function

        public function change(param1:String) : void
        {
            if (this.preventRequestSameSection && this._nextSection == param1)
            {
                return;
            }// end if
            this._nextSection = param1;
            this.say("change " + param1);
            this._waitingAccept = true;
            this.accept();
            return;
        }// end function

        public function get previous() : String
        {
            if (this._history)
            {
                if (this._history.length > 0)
                {
                    return this._history[this._history.length--];
                }// end if
            }// end if
            return null;
        }// end function

        public function get currentSection() : String
        {
            return this._currentSection ? (this._currentSection) : (this._default);
        }// end function

        public static function removeLevel(param1:String) : void
        {
            if (_levels)
            {
                if (_levels[param1])
                {
                    delete _levels[param1];
                }// end if
                throw new Error("Se ha intentado eliminar el nivel " + param1 + ", pero no existe este nivel");
            }// end if
            throw new Error("Se ha intentado eliminar el nivel " + param1 + ", pero no existe ning?n nivel");
        }// end function

        public static function addLevel(param1:String) : Flow
        {
            if (!_levels)
            {
                _levels = new Dictionary();
            }// end if
            if (_levels[param1])
            {
                _levels[param1].say("El nivel " + param1 + " ya estaba a?adido");
                return null;
            }// end if
            var _loc_2:* = new Flow;
            _loc_2.name = param1;
            _levels[param1] = _loc_2;
            return _loc_2;
        }// end function

        public static function dispatchEvent(... args) : void
        {
            if (disp == null)
            {
                return;
            }// end if
            disp.dispatchEvent.apply(null, args);
            return;
        }// end function

        public static function removeEventListener(... args) : void
        {
            if (disp == null)
            {
                return;
            }// end if
            disp.removeEventListener.apply(null, args);
            return;
        }// end function

        public static function addEventListener(... args) : void
        {
            if (disp == null)
            {
                disp = new EventDispatcher();
            }// end if
            disp.addEventListener.apply(null, args);
            return;
        }// end function

        public static function level(param1:String) : Flow
        {
            if (!_levels)
            {
                _levels = new Dictionary();
            }// end if
            if (_levels[param1] == undefined)
            {
                addLevel(param1);
                _levels[param1].say("Se ha a?adido autom?ticamente el nivel : " + param1);
            }// end if
            return _levels[param1];
        }// end function

        public static function checkLevel(param1:String) : Boolean
        {
            return _levels[param1];
        }// end function

    }
}
